#region License, Terms and Conditions
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
#endregion

using System;
using System.Linq;
using Pesta.DataAccess.Azure;
using Pesta.DataAccess.SqlServer;
using raya.Library;

namespace raya.Models.oauth
{
    public class oauth : Model
    {
        public class OAuthInfo
        {
            public string oauth_token { get; set; }
            public string oauth_callback { get; set; }
        }

        public class OAuthConsumerInfo
        {
            public string user_id { get; set; }
#if AZURE
            public string app_id { get; set; }
#else
            public int app_id { get; set; }
#endif
            public string consumer_key { get; set; }
            public string consumer_secret { get; set; }
        }

#if AZURE
        /// <summary>
        /// Returns an array with a oauth key and secret that can be used for 2 legged oauth request signing
        /// </summary>
        /// <param name="appId"></param>
        /// <returns></returns>
        static public OAuthConsumerInfo get_gadget_consumer(string appId)
        {
            using (var db = RayaDataContext.DB())
            {
                var result = db.oauthConsumers.Where(x => x.RowKey == appId && x.PartitionKey == "app").SingleOrDefault();
                if (result != null)
                {
                    var info = new OAuthConsumerInfo
                                   {
                                       user_id = result.user_id,
                                       app_id = result.app_id,
                                       consumer_key = result.consumer_key,
                                       consumer_secret = result.consumer_secret
                                   };
                    return info;
                }
               
                // no key for this user_id yet, auto-generate one on the fly
                var consumerKey = Guid.NewGuid().ToString();
                var consumerSecret = OAuthUtil.md5(Guid.NewGuid().ToString());
                var ret = new OAuthConsumerInfo
                {
                    app_id = appId,
                    consumer_key = consumerKey,
                    consumer_secret = consumerSecret
                };

                var oc = new OAuthConsumerRow("app",appId)
                {
                    user_id = "",
                    app_id = appId,
                    consumer_key = consumerKey,
                    consumer_secret = consumerSecret
                };
                db.InsertOnSubmit(AzureRayaDataContext.TableNames.oauthConsumers, oc);
                db.SubmitChanges();
                return ret;
            }
        }

        public static OAuthConsumerInfo get_person_consumer(string userId)
        {
            OAuthConsumerInfo data = new OAuthConsumerInfo();
            using (var db = RayaDataContext.DB())
            {
                var result = db.oauthConsumers
                    .Where(x => x.RowKey == userId && x.PartitionKey == "user")
                    .SingleOrDefault();
                if (result != null)
                {
                    data.consumer_key = result.consumer_key;
                    data.consumer_secret = result.consumer_secret;
                    data.user_id = userId;
                    return data;
                }

                // no key for this user_id yet, auto-generate one on the fly
                string consumerKey = Guid.NewGuid().ToString();
                // this is about as insecure as it could be (since it's 100% guessable)
                // please don't use this in production and come up with a REAL secret there :)
                string consumerSecret = OAuthUtil.md5(Guid.NewGuid().ToString());
                OAuthConsumerRow oAuthConsumerRow = new OAuthConsumerRow("user",userId)
                {
                    app_id = "",
                    user_id = userId,
                    consumer_key = consumerKey,
                    consumer_secret = consumerSecret
                };
                db.InsertOnSubmit(AzureRayaDataContext.TableNames.oauthConsumers, oAuthConsumerRow);
                db.SubmitChanges();

                data.consumer_key = oAuthConsumerRow.consumer_key;
                data.consumer_secret = oAuthConsumerRow.consumer_secret;
                data.user_id = userId;
                return data;
            }
        }
#else
        
        /// <summary>
        /// Returns an array with a oauth key and secret that can be used for 2 legged oauth request signing
        /// </summary>
        /// <param name="_app_id"></param>
        /// <returns></returns>
        public OAuthConsumerInfo get_gadget_consumer(string _app_id) 
        {
            int app_id = int.Parse(_app_id);
            using (var db= RayaDataContext.DB())
            {
                var res = (from o in db.oauth_consumers
                           where o.app_id == app_id
                           select new OAuthConsumerInfo
                                      {
                                          user_id = o.user_id.ToString(),
                                          app_id = o.app_id,
                                          consumer_key = o.consumer_key,
                                          consumer_secret = o.consumer_secret
                                      }).SingleOrDefault();
                if (res != null)
                {
                    return res;
                }
                // no key for this user_id yet, auto-generate one on the fly
                var consumerKey = Guid.NewGuid().ToString();
                var consumerSecret = OAuthUtil.md5(Guid.NewGuid().ToString());
                var ret = new OAuthConsumerInfo
                               {
                                   app_id = app_id,
                                   consumer_key = consumerKey,
                                   consumer_secret = consumerSecret
                               };
                var oc = new oauth_consumer
                             {
                                 user_id = 0,
                                 app_id = app_id,
                                 consumer_key = consumerKey,
                                 consumer_secret = consumerSecret
                             };
                db.oauth_consumers.InsertOnSubmit(oc);
                db.SubmitChanges();
                return ret;
            }
        }

        /// <summary>
        /// Returns an array with a oauth key and secret that can be used for 3 legged oauth request signing
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        static public OAuthConsumerInfo get_person_consumer(int userId)
        {
            OAuthConsumerInfo data = new OAuthConsumerInfo();
            using (var db= RayaDataContext.DB())
            {
                var res = (from o in db.oauth_consumers
                            where o.user_id == userId
                            select o).SingleOrDefault();
                if (res != null)
                {
                    data.consumer_key = res.consumer_key;
                    data.consumer_secret = res.consumer_secret;
                    data.user_id = userId.ToString();
                    return data;
                }
		        
                // no key for this user_id yet, auto-generate one on the fly
                string consumerKey = Guid.NewGuid().ToString();
                // this is about as insecure as it could be (since it's 100% guessable)
                // please don't use this in production and come up with a REAL secret there :)
                string consumerSecret = OAuthUtil.md5(Guid.NewGuid().ToString());
                var ret = new oauth_consumer
                               {
                                   app_id = 0,
                                   user_id = userId,
                                   consumer_key = consumerKey,
                                   consumer_secret = consumerSecret
                               };
                db.oauth_consumers.InsertOnSubmit(ret);
                db.SubmitChanges();

                data.consumer_key = ret.consumer_key;
                data.consumer_secret = ret.consumer_secret;
                data.user_id = userId.ToString();
                return data;
            }
        }
#endif
    }
}